<!DOCTYPE html>


<html lang="zh-CN">


<head>
  <meta charset="utf-8" />
    
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
  <title>
    IT运维面试问题总结-数据库、监控、网络管理.md |  
  </title>
  <meta name="generator" content="hexo-theme-ayer">
  
  <link rel="shortcut icon" href="/favicon.ico" />
  
  
<link rel="stylesheet" href="/dist/main.css">

  
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Shen-Yu/cdn/css/remixicon.min.css">

  
<link rel="stylesheet" href="/css/custom.css">

  
  
<script src="https://cdn.jsdelivr.net/npm/pace-js@1.0.2/pace.min.js"></script>

  
  

  

</head>

</html>

<body>
  <div id="app">
    
      
    <main class="content on">
      <section class="outer">
  <article
  id="post-interview/IT运维面试问题总结-数据库、监控、网络管理"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h1 class="article-title sea-center" style="border-left:0" itemprop="name">
  IT运维面试问题总结-数据库、监控、网络管理.md
</h1>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/11/11/interview/IT%E8%BF%90%E7%BB%B4%E9%9D%A2%E8%AF%95%E9%97%AE%E9%A2%98%E6%80%BB%E7%BB%93-%E6%95%B0%E6%8D%AE%E5%BA%93%E3%80%81%E7%9B%91%E6%8E%A7%E3%80%81%E7%BD%91%E7%BB%9C%E7%AE%A1%E7%90%86/" class="article-date">
  <time datetime="2020-11-10T16:00:00.000Z" itemprop="datePublished">2020-11-11</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/interview/">interview</a>
  </div>
  
<div class="word_count">
    <span class="post-time">
        <span class="post-meta-item-icon">
            <i class="ri-quill-pen-line"></i>
            <span class="post-meta-item-text"> 字数统计:</span>
            <span class="post-count">9k</span>
        </span>
    </span>

    <span class="post-time">
        &nbsp; | &nbsp;
        <span class="post-meta-item-icon">
            <i class="ri-book-open-line"></i>
            <span class="post-meta-item-text"> 阅读时长≈</span>
            <span class="post-count">31 分钟</span>
        </span>
    </span>
</div>
 
    </div>
      
    <div class="tocbot"></div>




  
    <div class="article-entry" itemprop="articleBody">
       
  <h1 id="IT运维面试问题总结-数据库、监控、网络管理"><a href="#IT运维面试问题总结-数据库、监控、网络管理" class="headerlink" title="IT运维面试问题总结-数据库、监控、网络管理"></a>IT运维面试问题总结-数据库、监控、网络管理</h1><h2 id="数据库"><a href="#数据库" class="headerlink" title="数据库"></a>数据库</h2><h3 id="简述NoSQL是什么？"><a href="#简述NoSQL是什么？" class="headerlink" title="简述NoSQL是什么？"></a>简述NoSQL是什么？</h3><p>NoSQL，指的是非关系型的数据库。NoSQL 有时也称作 Not Only SQL（意即”不仅仅是SQL”） 的缩写，其显著特点是不使用SQL作为查询语言，数据存储不需要特定的表格模式。</p>
<h3 id="简述NoSQL（非关系型）数据库和SQL（关系型）数据库的区别？"><a href="#简述NoSQL（非关系型）数据库和SQL（关系型）数据库的区别？" class="headerlink" title="简述NoSQL（非关系型）数据库和SQL（关系型）数据库的区别？"></a>简述NoSQL（非关系型）数据库和SQL（关系型）数据库的区别？</h3><p>NoSQL和SQL的主要区别有如下区别：</p>
<ul>
<li><p>存储方式：</p>
</li>
<li><ul>
<li>关系型数据库是表格式的，因此存储在表的行和列中。他们之间很容易关联协作存储，提取数据很方便。</li>
<li>NoSQL数据库则与其相反，它是大块的组合在一起。通常存储在数据集中，就像文档、键值对或者图结构。</li>
</ul>
</li>
<li><p>存储结构</p>
</li>
<li><ul>
<li>关系型数据库对应的是结构化数据，数据表都预先定义了结构（列的定义），结构描述了数据的形式和内容。预定义结构带来了可靠性和稳定性，但是修改这些数据比较困难。</li>
<li>NoSQL数据库基于动态结构，使用与非结构化数据。由于NoSQL数据库是动态结构，可以很容易适应数据类型和结构的变化。</li>
</ul>
</li>
<li><p>存储规范</p>
</li>
<li><ul>
<li>关系型数据库的数据存储为了更高的规范性，把数据分割为最小的关系表以避免重复，获得精简的空间利用。</li>
<li>NoSQL数据存储在平面数据集中，数据经常可能会重复。单个数据库很少被分隔开，而是存储成了一个整体，这样整块数据更加便于读写 。</li>
</ul>
</li>
<li><p>存储扩展</p>
</li>
<li><ul>
<li>关系型数据库数据存储在关系表中，操作的性能瓶颈可能涉及到多个表，需要通过提升计算机性能来克服，因此更多是采用纵向扩展</li>
<li>NoSQL数据库是横向扩展的，它的存储天然就是分布式的，可以通过给资源池添加更多的普通数据库服务器来分担负载。</li>
</ul>
</li>
<li><p>查询方式</p>
</li>
<li><ul>
<li>关系型数据库通过结构化查询语言来操作数据库（即通常说的SQL）。SQL支持数据库CURD操作的功能非常强大，是业界的标准用法。</li>
<li>NoSQL查询以块为单元操作数据，使用的是非结构化查询语言（UnQl），它是没有标准的。</li>
<li>关系型数据库表中主键的概念对应NoSQL中存储文档的ID。</li>
<li>关系型数据库使用预定义优化方式（比如索引）来加快查询操作，而NoSQL更简单更精确的数据访问模式。</li>
</ul>
</li>
<li><p>事务</p>
</li>
<li><ul>
<li>关系型数据库遵循ACID规则（原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)）。</li>
<li>NoSQL数据库遵循BASE原则（基本可用（Basically Availble）、软/柔性事务（Soft-state ）、最终一致性（Eventual Consistency））。</li>
<li>由于关系型数据库的数据强一致性，所以对事务的支持很好。关系型数据库支持对事务原子性细粒度控制，并且易于回滚事务。</li>
<li>NoSQL数据库是在CAP（一致性、可用性、分区容忍度）中任选两项，因为基于节点的分布式系统中，不可能同时全部满足，所以对事务的支持不是很好。</li>
</ul>
</li>
</ul>
<h3 id="简述NoSQL（非关系型）数据库和SQL（关系型）数据库的各自主要代表？"><a href="#简述NoSQL（非关系型）数据库和SQL（关系型）数据库的各自主要代表？" class="headerlink" title="简述NoSQL（非关系型）数据库和SQL（关系型）数据库的各自主要代表？"></a>简述NoSQL（非关系型）数据库和SQL（关系型）数据库的各自主要代表？</h3><p>SQL：MariaDB、MySQL、SQLite、SQLServer、Oracle、PostgreSQL。</p>
<p>NoSQL代表：Redis、MongoDB、Memcache、HBASE。</p>
<h3 id="简述MongoDB及其特点？"><a href="#简述MongoDB及其特点？" class="headerlink" title="简述MongoDB及其特点？"></a>简述MongoDB及其特点？</h3><p>MongoDB是一个开源的、基于分布式的、面向文档存储的非关系型数据库。是非关系型数据库当中功能最丰富、最像关系数据库的。其主要特点如下：</p>
<ul>
<li><code>查询丰富</code>：MongoDB最大的特点是支持的查询语言非常强大，其语法有点类似于面向对象的查询语言，几乎可以实现类似关系数据库单表查询的绝大部分功能，而且还支持对数据建立索引。</li>
<li><code>面向文档</code>：文档就是存储在MongoDB中的一条记录,是一个由键值对组成的数据结构。</li>
<li><code>模式自由</code>：MongoDB每一个Document都包含了元数据信息，每个文档之间不强迫要求使用相同的格式，同时他们也支持各种索引。</li>
<li><code>高可用性</code>：MongoDB支持在复制集(Replica Set)通过异步复制达到故障转移，自动恢复，集群中主服务器崩溃停止服务和丢失数据，备份服务器通过选举获得大多数投票成为主节点，以此来实现高可用。</li>
<li><code>水平拓展</code>：MongoDB支持分片技术，它能够支持并行处理和水平扩展。</li>
<li><code>支持丰富</code>：MongoDB另外还提供了丰富的BSON数据类型，还有MongoDB的官方不同语言的driver支持(C/C++、C#、Java、Node.js、Perl、PHP、Python、Ruby、Scala)。</li>
</ul>
<h3 id="简述MongoDB的优势有哪些？"><a href="#简述MongoDB的优势有哪些？" class="headerlink" title="简述MongoDB的优势有哪些？"></a>简述MongoDB的优势有哪些？</h3><ul>
<li>面向文档的存储：以 JSON 格式的文档保存数据。</li>
<li>任何属性都可以建立索引。</li>
<li>复制以及高可扩展性。</li>
<li>自动分片。</li>
<li>丰富的查询功能。</li>
<li>快速的即时更新。</li>
</ul>
<h3 id="简述MongoDB适应的场景和不适用的场景？"><a href="#简述MongoDB适应的场景和不适用的场景？" class="headerlink" title="简述MongoDB适应的场景和不适用的场景？"></a>简述MongoDB适应的场景和不适用的场景？</h3><p>MongoDB属于典型的非关系型数据库。</p>
<ul>
<li><p>主要适应场景</p>
</li>
<li><ul>
<li>网站实时数据：MongoDB 非常适合实时的插入，更新与查询，并具备网站实时数据存储所需的复制及高度伸缩性。</li>
<li>数据缓存：由于性能很高，MongoDB 也适合作为信息基础设施的缓存层。在系统重启之后，由 MongoDB 搭建的持久化缓存层可以避免下层的数据源过载。</li>
<li>高伸缩性场景：MongoDB 非常适合由数十或数百台服务器组成的数据库。</li>
<li>对象或 JSON 数据存储：MongoDB 的 BSON 数据格式非常适合文档化格式的存储及查询。</li>
</ul>
</li>
<li><p>不适应场景</p>
</li>
<li><ul>
<li>高度事务性系统：例如银行或会计系统。传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序。</li>
<li>传统的商业智能应用：针对特定问题的 BI 数据库会对产生高度优化的查询方式。对于此类应用，数据仓库可能是更合适的选择。</li>
<li>需要复杂 SQL 查询的场景。</li>
</ul>
</li>
</ul>
<h3 id="简述MongoDB中的库、集合、文档？"><a href="#简述MongoDB中的库、集合、文档？" class="headerlink" title="简述MongoDB中的库、集合、文档？"></a>简述MongoDB中的库、集合、文档？</h3><ul>
<li><code>库</code>：MongoDB可以建立多个数据库，MongoDB默认数据库为”db”。MongoDB的单个实例可以容纳多个独立的数据库，每一个都有自己的集合和权限，不同的数据库也放置在不同的文件中。</li>
<li><code>集合</code>：MongoDB集合就是 MongoDB 文档组，类似于 RDBMS （关系数据库中的表格）。集合存在于数据库中，集合没有固定的结构。</li>
<li><code>文档</code>：MongoDB的Document是一组键值(key-value)对(即 BSON)，相当于关系型数据库的行。且不需要设置相同的字段，并且相同的字段不需要相同的数据类型。</li>
</ul>
<h3 id="简述MongoDB支持的常见数据类型？"><a href="#简述MongoDB支持的常见数据类型？" class="headerlink" title="简述MongoDB支持的常见数据类型？"></a>简述MongoDB支持的常见数据类型？</h3><p>MongoDB支持丰富的数据类型，常见的有：</p>
<ul>
<li>String：字符串。存储数据常用的数据类型。</li>
<li>Integer：整型数值。用于存储数值。</li>
<li>Boolean：布尔值。用于存储布尔值（真/假）。</li>
<li>Array：用于将数组或列表或多个值存储为一个键。</li>
<li>Date：日期时间。用 UNIX 时间格式来存储当前日期或时间。</li>
<li>Binary Data：二进制数据。用于存储二进制数据。</li>
<li>Code：代码类型。用于在文档中存储 JavaScript 代码。</li>
<li>Regular expression：正则表达式类型。用于存储正则表达式。</li>
</ul>
<h3 id="简述MongoDB索引及其作用？"><a href="#简述MongoDB索引及其作用？" class="headerlink" title="简述MongoDB索引及其作用？"></a>简述MongoDB索引及其作用？</h3><p>索引通常能够极大的提高查询的效率，如果没有索引，MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。</p>
<p>这种扫描全集合的查询效率是非常低的，特别在处理大量的数据时，查询可能要花费几十秒甚至几分钟，这对网站的性能是非常致命的。</p>
<p>索引是特殊的数据结构，索引存储在一个易于遍历读取的数据集合中，索引是对数据库表中一列或多列的值进行排序的一种结构。</p>
<h3 id="简述MongoDB常见的索引有哪些？"><a href="#简述MongoDB常见的索引有哪些？" class="headerlink" title="简述MongoDB常见的索引有哪些？"></a>简述MongoDB常见的索引有哪些？</h3><p>MongoDB常见的索引有：</p>
<ul>
<li>单字段索引（Single Field Indexes）</li>
<li>符合索引（Compound Indexes）</li>
<li>多键索引（Multikey Indexes）</li>
<li>全文索引（Text Indexes）</li>
<li>Hash索引（Hash Indexes）</li>
<li>通配符索引（Wildcard Indexes）</li>
</ul>
<h3 id="简述MongoDB复制（本）集原理？"><a href="#简述MongoDB复制（本）集原理？" class="headerlink" title="简述MongoDB复制（本）集原理？"></a>简述MongoDB复制（本）集原理？</h3><p>mongodb的复制至少需要两个节点。其中一个是主节点，负责处理客户端请求，其余的都是从节点，负责复制主节点上的数据。</p>
<p>mongodb各个节点常见的搭配方式为：一主一从、一主多从。</p>
<p>主节点记录在其上的所有操作oplog，从节点定期轮询主节点获取这些操作，然后对自己的数据副本执行这些操作，从而保证从节点的数据与主节点一致。</p>
<h3 id="简述MongoDB的复制过程？"><a href="#简述MongoDB的复制过程？" class="headerlink" title="简述MongoDB的复制过程？"></a>简述MongoDB的复制过程？</h3><p>Primary节点写入数据，Secondary通过读取Primary的oplog（即Primary的oplog.rs表）得到复制信息，开始复制数据并且将复制信息写入到自己的oplog。如果某个操作失败，则备份节点停止从当前数据源复制数据。如果某个备份节点由于某些原因挂掉了，当重新启动后，就会自动从oplog的最后一个操作开始同步。同步完成后，将信息写入自己的oplog，由于复制操作是先复制数据，复制完成后再写入oplog，有可能相同的操作会同步两份，MongoDB设定将oplog的同一个操作执行多次，与执行一次的效果是一样的。</p>
<p>当Primary节点完成数据操作后，Secondary的数据同步过程如下：</p>
<ul>
<li>1、检查自己local库的oplog.rs集合找出最近的时间戳。</li>
<li>2、检查Primary节点local库oplog.rs集合，找出大于此时间戳的记录。</li>
<li>3、将找到的记录插入到自己的oplog.rs集合中，并执行这些操作。</li>
</ul>
<h3 id="简述MongoDB副本集及其特点？"><a href="#简述MongoDB副本集及其特点？" class="headerlink" title="简述MongoDB副本集及其特点？"></a>简述MongoDB副本集及其特点？</h3><p>MongoDB副本集是一组Mongod维护相同数据集的实例，副本集可以包含多个数据承载点和多个仲裁点。在承载数据的节点中，仅有一个节点被视为主节点，其他节点称为次节点。</p>
<p>主要特点：</p>
<ul>
<li>N 个节点的集群，任何节点可作为主节点，由选举产生；</li>
<li>最小构成是：primary，secondary，arbiter，一般部署是：primary，2 secondary。</li>
<li>所有写入操作都在主节点上，同时具有自动故障转移，自动恢复；</li>
<li>成员数应该为奇数，如果为偶数的情况下添加arbiter，arbiter不保存数据，只投票。</li>
</ul>
<h3 id="简述MongoDB有哪些特殊成员？"><a href="#简述MongoDB有哪些特殊成员？" class="headerlink" title="简述MongoDB有哪些特殊成员？"></a>简述MongoDB有哪些特殊成员？</h3><p>MongoDB中Secondary角色存在一些特殊的成员类型：</p>
<ul>
<li>Priority 0（优先级0型）：不能升为主，可以用于多数据中心场景；</li>
<li>Hidden（隐藏型）：对客户端来说是不可见的，一般用作备份或统计报告用；</li>
<li>Delayed（延迟型）：数据比副集晚，一般用作 rolling backup 或历史快照。</li>
<li>Vote（投票型）：仅参与投票。</li>
</ul>
<h3 id="简述MongoDB分片集群？"><a href="#简述MongoDB分片集群？" class="headerlink" title="简述MongoDB分片集群？"></a>简述MongoDB分片集群？</h3><p>MongoDB分片集群（Sharded Cluster）：主要利用分片技术，使数据分散存储到多个分片（Shard）上，来实现高可扩展性。</p>
<p>分片是将数据水平切分到不同的物理节点。当数据量越来越大时，单台机器有可能无法存储数据或读取写入吞吐量有所降低，利用分片技术可以添加更多的机器来应对数据量增加以及读写操作的要求。</p>
<h3 id="简述MongoDB分片集群相对副本集的优势？"><a href="#简述MongoDB分片集群相对副本集的优势？" class="headerlink" title="简述MongoDB分片集群相对副本集的优势？"></a>简述MongoDB分片集群相对副本集的优势？</h3><p>MongoDB分片集群主要可以解决副本集如下的不足：</p>
<ul>
<li>副本集所有的写入操作都位于主节点；</li>
<li>延迟的敏感数据会在主节点查询；</li>
<li>单个副本集限制在12个节点；</li>
<li>当请求量巨大时会出现内存不足；</li>
<li>本地磁盘不足；</li>
<li>垂直扩展价格昂贵。</li>
</ul>
<h3 id="简述MongoDB分片集群的优势？"><a href="#简述MongoDB分片集群的优势？" class="headerlink" title="简述MongoDB分片集群的优势？"></a>简述MongoDB分片集群的优势？</h3><p>MongoDB分片集群主要有如下优势：</p>
<ul>
<li>使用分片减少了每个分片需要处理的请求数：通过水平扩展，群集可以提高自己的存储容量。比如，当插入一条数据时，应用只需要访问存储这条数据的分片。</li>
<li>使用分片减少了每个分片存储的数据：分片的优势在于提供类似线性增长的架构，提高数据可用性，提高大型数据库查询服务器的性能。当MongoDB单点数据库服务器存储成为瓶颈、单点数据库服务器的性能成为瓶颈或需要部署大型应用以充分利用内存时，可以使用分片技术。</li>
</ul>
<h3 id="简述MongoDB分片集群的架构组件？"><a href="#简述MongoDB分片集群的架构组件？" class="headerlink" title="简述MongoDB分片集群的架构组件？"></a>简述MongoDB分片集群的架构组件？</h3><p>MongoDB架构组件主要有：</p>
<ul>
<li>Shard：用于存储实际的数据块，实际生产环境中一个shard server角色可由几台机器组成一个replica set承担，防止主机单点故障。</li>
<li>Config Server：mongod实例，存储了整个 ClusterMetadata，其中包括 chunk信息。</li>
<li>Query Routers：前端路由，客户端由此接入，且让整个集群看上去像单一数据库，前端应用可以透明使用。</li>
</ul>
<h3 id="简述MongoDB分片集群和副本集群的区别？"><a href="#简述MongoDB分片集群和副本集群的区别？" class="headerlink" title="简述MongoDB分片集群和副本集群的区别？"></a>简述MongoDB分片集群和副本集群的区别？</h3><p>副本集不是为了提高读性能存在的，在进行oplog的时候，读操作是被阻塞的；</p>
<p>提高读取性能应该使用分片和索引，它的存在更多是作为数据冗余，备份。</p>
<h3 id="简述MongoDB的几种分片策略及其相互之间的差异？"><a href="#简述MongoDB的几种分片策略及其相互之间的差异？" class="headerlink" title="简述MongoDB的几种分片策略及其相互之间的差异？"></a>简述MongoDB的几种分片策略及其相互之间的差异？</h3><p>MongoDB的数据划分是基于集合级别为标准，通过shard key来划分集合数据。主要分片策略有如下三种：</p>
<ul>
<li>范围划分：通过shard key值将数据集划分到不同的范围就称为基于范围划分。对于数值型的shard key：可以虚构一条从负无穷到正无穷的直线（理解为x轴），每个shard key 值都落在这条直线的某个点上，然后MongoDB把这条线划分为许多更小的没有重复的范围成为块（chunks），一个chunk就是某些最小值到最大值的范围。</li>
<li>散列划分：MongoDB计算每个字段的hash值，然后用这些hash值建立chunks。基于散列值的数据分布有助于更均匀的数据分布，尤其是在shard key单调变化的数据集中。</li>
<li>自定义标签划分：MongoDB支持通过自定义标签标记分片的方式直接平衡数据分布策略，可以创建标签并且将它们与shard key值的范围进行关联，然后分配这些标签到各个分片上，最终平衡器转移带有标签标记的数据到对应的分片上，确保集群总是按标签描述的那样进行数据分布。标签是控制平衡器行为及集群中块分布的主要方法。</li>
</ul>
<p><code>差异</code>：</p>
<ul>
<li>基于范围划分对于范围查询比较高效。假设在shard key上进行范围查询，查询路由很容易能够知道哪些块与这个范围重叠，然后把相关查询按照这个路线发送到仅仅包含这些chunks的分片。</li>
<li>基于范围划分很容易导致数据不均匀分布，这样会削弱分片集群的功能。</li>
<li>基于散列划分是以牺牲高效范围查询为代价，它能够均匀的分布数据，散列值能够保证数据随机分布到各个分片上。</li>
</ul>
<h3 id="简述MongoDB分片集群采取什么方式确保数据分布的平衡？"><a href="#简述MongoDB分片集群采取什么方式确保数据分布的平衡？" class="headerlink" title="简述MongoDB分片集群采取什么方式确保数据分布的平衡？"></a>简述MongoDB分片集群采取什么方式确保数据分布的平衡？</h3><p>新加入的数据及服务器都会导致集群数据分布不平衡，MongoDB采用两种方式确保数据分布的平衡：</p>
<ul>
<li><p>拆分</p>
<p>拆分是一个后台进程，防止块变得太大。当一个块增长到指定块大小的时候，拆分进程就会块一分为二，整个拆分过程是高效的。不会涉及到数据的迁移等操作。</p>
</li>
<li><p>平衡</p>
<p>平衡器是一个后台进程，管理块的迁移。平衡器能够运行在集群任何的mongd实例上。当集群中数据分布不均匀时，平衡器就会将某个分片中比较多的块迁移到拥有块较少的分片中，直到数据分片平衡为止。</p>
<p>分片采用后台操作的方式管理着源分片和目标分片之间块的迁移。在迁移的过程中，源分片中的块会将所有文档发送到目标分片中，然后目标分片会获取并应用这些变化。最后，更新配置服务器上关于块位置元数据。</p>
</li>
</ul>
<h3 id="简述MongoDB备份及恢复方式？"><a href="#简述MongoDB备份及恢复方式？" class="headerlink" title="简述MongoDB备份及恢复方式？"></a>简述MongoDB备份及恢复方式？</h3><p>mongodb备份恢复方式通常有以下三种：</p>
<ul>
<li><code>文件快照方式</code>：此方式相对简单，需要系统文件支持快照和mongod必须启用journal。可以在任何时刻创建快照。恢复时，确保没有运行mongod，执行快照恢复操作命令，然后启动mongod进程，mongod将重放journal日志。</li>
<li><code>复制数据文件方式</code>：直接拷贝数据目录下的一切文件，但是在拷贝过程中必须阻止数据文件发生更改。因此需要对数据库加锁，以防止数据写入。恢复时，确保mongod没有运行，清空数据目录，将备份的数据拷贝到数据目录下，然后启动mongod。</li>
<li><code>使用mongodump和mongorestore方式</code>：在Mongodb中我们使用mongodump命令来备份MongoDB数据。该命令可以导出所有数据到指定目录中。恢复时，使用mongorestore命令来恢复MongoDB数据。该命令可以从指定目录恢复相应数据。</li>
</ul>
<h3 id="简述MongoDB的聚合操作？"><a href="#简述MongoDB的聚合操作？" class="headerlink" title="简述MongoDB的聚合操作？"></a>简述MongoDB的聚合操作？</h3><p>聚合操作能够处理数据记录并返回计算结果。聚合操作能将多个文档中的值组合起来，对成组数据执行各种操作，返回单一的结果。它相当于 SQL 中的 count(*) 组合 group by。对于 MongoDB 中的聚合操作，应该使用aggregate()方法。</p>
<h3 id="简述MongoDB中的GridFS机制？"><a href="#简述MongoDB中的GridFS机制？" class="headerlink" title="简述MongoDB中的GridFS机制？"></a>简述MongoDB中的GridFS机制？</h3><p>GridFS是一种将大型文件存储在MongoDB中的文件规范。使用GridFS可以将大文件分隔成多个小文档存放，这样我们能够有效的保存大文档，而且解决了BSON对象有限制的问题。</p>
<h3 id="简述MongoDB针对查询优化的措施？"><a href="#简述MongoDB针对查询优化的措施？" class="headerlink" title="简述MongoDB针对查询优化的措施？"></a>简述MongoDB针对查询优化的措施？</h3><p>MongoDB查询优化大致可能从如下步骤着手：</p>
<ul>
<li><p>第一步：找出慢速查询</p>
<p>如下方式开启内置的查询分析器,记录读写操作效率：</p>
<p>db.setProfilingLevel(n,{m}),n的取值可选0,1,2；</p>
<p>查询监控结果：监控结果保存在一个特殊的集合system.profile里。</p>
</li>
<li><ul>
<li>0：默认值，表示不记录；</li>
<li>1：表示记录慢速操作，如果值为1，m必须赋值单位为ms，用于定义慢速查询时间的阈值；</li>
<li>2：表示记录所有的读写操作。</li>
</ul>
</li>
<li><p>第二步：分析慢速查询</p>
<p>找出慢速查询的原因，通常可能的原因有：应用程序设计不合理、不正确的数据模型、硬件配置问题、缺少索引等</p>
</li>
<li><p>第三部：根据不同的分析结果进行优化，如建立索引。</p>
</li>
</ul>
<h3 id="简述MongoDB的更新操作是否会立刻fsync到磁盘？"><a href="#简述MongoDB的更新操作是否会立刻fsync到磁盘？" class="headerlink" title="简述MongoDB的更新操作是否会立刻fsync到磁盘？"></a>简述MongoDB的更新操作是否会立刻fsync到磁盘？</h3><p>不会，磁盘写操作默认是延时执行的，写操作可能在两三秒（默认在60秒内）后到达磁盘，可通过syncPeriodSecs参数进行配置。</p>
<h3 id="简述MySQL索引及其作用？"><a href="#简述MySQL索引及其作用？" class="headerlink" title="简述MySQL索引及其作用？"></a>简述MySQL索引及其作用？</h3><p>是数据库管理系统中一个排序的数据结构，根据不同的存储引擎索引分为Hash索引、B+树索引等。常见的InnoDB存储引擎的默认索引实现为：B+树索引。</p>
<p>索引可以协助快速查询、更新数据库表中数据。</p>
<h3 id="简述MySQL中什么是事务？"><a href="#简述MySQL中什么是事务？" class="headerlink" title="简述MySQL中什么是事务？"></a>简述MySQL中什么是事务？</h3><p>事务是一系列的操作，需要要符合ACID特性，即：事务中的操作要么全部成功，要么全部失败。</p>
<h3 id="简述MySQL事务之间的隔离？"><a href="#简述MySQL事务之间的隔离？" class="headerlink" title="简述MySQL事务之间的隔离？"></a>简述MySQL事务之间的隔离？</h3><p>MySQL事务支持如下四种隔离：</p>
<ul>
<li><code>未提交读</code>(Read Uncommitted)：允许脏读，其他事务只要修改了数据，即使未提交，本事务也能看到修改后的数据值。也就是可能读取到其他会话中未提交事务修改的数据。</li>
<li><code>提交读</code>(Read Committed)：只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)。</li>
<li><code>可重复读</code>(Repeated Read)：可重复读。无论其他事务是否修改并提交了数据，在这个事务中看到的数据值始终不受其他事务影响。</li>
<li><code>串行读</code>(Serializable)：完全串行化的读，每次读都需要获得表级共享锁，读写相互都会阻塞。</li>
</ul>
<h3 id="简述MySQL锁及其作用？"><a href="#简述MySQL锁及其作用？" class="headerlink" title="简述MySQL锁及其作用？"></a>简述MySQL锁及其作用？</h3><p>锁机制是为了避免，在数据库有并发事务的时候，可能会产生数据的不一致而诞生的的一个机制。锁从类别上分为：</p>
<ul>
<li><code>共享锁</code>：又叫做读锁，当用户要进行数据的读取时，对数据加上共享锁，共享锁可以同时加上多个。</li>
<li><code>排他锁</code>：又叫做写锁，当用户要进行数据的写入时，对数据加上排他锁，排他锁只可以加一个，他和其他的排他锁,共享锁都相斥。</li>
</ul>
<h3 id="简述MySQL表中为什么建议添加主键？"><a href="#简述MySQL表中为什么建议添加主键？" class="headerlink" title="简述MySQL表中为什么建议添加主键？"></a>简述MySQL表中为什么建议添加主键？</h3><p>主键是数据库确保数据行在整张表唯一性的保障，即使数据库中表没有主键，也建议添加一个自增长的ID列作为主键，设定了主键之后，在后续的删改查的时候可能更加快速以及确保操作数据范围安全。</p>
<h3 id="简述MySQL所支持的存储引擎？"><a href="#简述MySQL所支持的存储引擎？" class="headerlink" title="简述MySQL所支持的存储引擎？"></a>简述MySQL所支持的存储引擎？</h3><p>MySQL支持多种存储引擎，常见的有InnoDB、MyISAM、Memory、Archive等。通常使用InnoDB引擎都是最合适的，InnoDB也是MySQL的默认存储引擎。</p>
<h3 id="简述MySQL-InnoDB引擎和MyISAM引擎的差异？"><a href="#简述MySQL-InnoDB引擎和MyISAM引擎的差异？" class="headerlink" title="简述MySQL InnoDB引擎和MyISAM引擎的差异？"></a>简述MySQL InnoDB引擎和MyISAM引擎的差异？</h3><ul>
<li>InnoDB支持事物，而MyISAM不支持事物。</li>
<li>InnoDB支持行级锁，而MyISAM支持表级锁。</li>
<li>InnoDB支持MVCC, 而MyISAM不支持。</li>
<li>InnoDB支持外键，而MyISAM不支持。</li>
<li>InnoDB不支持全文索引，而MyISAM支持。</li>
</ul>
<h3 id="简述MySQL主从复制过程？"><a href="#简述MySQL主从复制过程？" class="headerlink" title="简述MySQL主从复制过程？"></a>简述MySQL主从复制过程？</h3><ul>
<li>1、Slave上面的IO线程连接上Master，并请求从指定日志文件的指定位置（或者从最开始的日志）之后的日志内容；</li>
<li>2、Master接收到来自Slave的IO线程的请求后，通过负责复制的IO线程根据请求信息读取指定日志指定位置之后的日志信息，返回给Slave端的IO线程。返回信息中除了日志所包含的信息之外，还包括本次返回的信息在Master端binary log文件的名称以及在Binary log中的位置；</li>
<li>3、Slave的IO线程收到信息后，将接收到的日志内容依次写入到Slave端的RelayLog文件（mysql-relay-lin.xxxxx）的最末端，并将读取到的Master端的bin-log的文件名和位置记录到master-info文件中，以便在下一次读取的时候能够明确知道从什么位置开始读取日志；</li>
<li>4、Slave的SQL线程检测到Relay Log中新增加了内容后，会马上解析该Log文件中的内容成为在Master端真实执行时候的那些可执行的查询或操作语句，并在自身执行那些查询或操作语句，这样，实际上就是在master端和Slave端执行了同样的查询或操作语句，所以两端的数据是完全一样的。</li>
</ul>
<h3 id="简述MySQL常见的读写分离方案？"><a href="#简述MySQL常见的读写分离方案？" class="headerlink" title="简述MySQL常见的读写分离方案？"></a>简述MySQL常见的读写分离方案？</h3><p>MySQL+Amoeba读写分离方案：Amoeba(变形虫)项目，这个工具致力于MySQL的分布式数据库前端代理层，它主要在应用层访问MySQL的时候充当SQL路由功能。具有负载均衡、高可用性、SQL 过滤、读写分离、可路由相关的到目标数据库、可并发请求多台数据库合并结果。通过Amoeba你能够完成多数据源的高可用、负载均衡、数据切片、读写分离的功能。</p>
<p>MySQL+MMM读写分离方案：MMM即Multi-Master Replication Manager for MySQL，mysql多主复制管理器是关于mysql主主复制配置的监控、故障转移和管理的一套可伸缩的脚本套件(在任何时候只有一个节点可以被写入)。MMM也能对从服务器进行读负载均衡，通过MMM方案能实现服务器的故障转移，从而实现mysql的高可用。MMM不仅能提供浮动IP的功能，如果当前的主服务器挂掉后，会将你后端的从服务器自动转向新的主服务器进行同步复制，不用手工更改同步配置。</p>
<h3 id="简述MySQL常见的高可用方案？"><a href="#简述MySQL常见的高可用方案？" class="headerlink" title="简述MySQL常见的高可用方案？"></a>简述MySQL常见的高可用方案？</h3><ul>
<li><code>MySQL主从复制</code>：Mysql内建的复制功能是构建大型，高性能应用程序的基础。将Mysql的数据分布在多个节点（slaves）之上，复制过程中一个服务器充当主服务器，而一个或多个其它服务器充当从服务器。主服务器将更新写入二进制日志文件，并维护文件的一个索引以跟踪日志循环。这些日志可以记录发送到从服务器的更新。</li>
<li><code>MySQL双主</code>：参考MySQL主从复制。</li>
<li><code>MySQL双主多从</code>：参考MySQL主从复制。</li>
<li><code>MySQL复制+Keepalived高可用</code>：MySQL自身的复制，对外基于Keepalived技术，暴露一个VIP，从而实现高可用。</li>
<li><code>Heartbeat + MySQL 实现MySQL的高可用</code>：通过Heartbeat的心跳检测和资源接管、集群中服务的监测、失效切换等功能，结合MySQL来实现高可用性。</li>
</ul>
<h3 id="简述MySQL常见的优化措施？"><a href="#简述MySQL常见的优化措施？" class="headerlink" title="简述MySQL常见的优化措施？"></a>简述MySQL常见的优化措施？</h3><p>MySQL可通过如下方式优化：</p>
<ul>
<li>1、开启查询缓存，优化查询。</li>
<li>2、使用explain判断select查询，从而分析查询语句或是表结构的性能瓶颈，然后有针对性的进行优化。</li>
<li>3、为搜索字段建索引</li>
<li>4、对于有限定范围取值的字段，推荐使用 ENUM 而不是 VARCHAR。</li>
<li>5、垂直分表。</li>
<li>6、选择正确的存储引擎。</li>
</ul>
<h3 id="简述MySQL常见备份方式和工具？"><a href="#简述MySQL常见备份方式和工具？" class="headerlink" title="简述MySQL常见备份方式和工具？"></a>简述MySQL常见备份方式和工具？</h3><ul>
<li><p>MySQL自带</p>
<p>mysqldump：mysqldump支持基于innodb的热备份，使用mysqldump完全备份+二进制日志可以实现基于时间点的恢复，通常适合备份数据比较小的场景 。</p>
</li>
<li><p>系统层面</p>
<p>tar备份：可以使用tar之类的系统命令对整个数据库目录进行打包备份。</p>
<p>lvm快照备份：可基于文件系统的LVM制作快照，进行对整个数据库目录所在的逻辑卷备份。</p>
</li>
<li><p>第三方备份工具</p>
<p>可使用其他第三方工具进行备份，如xtrabackup工具，该工具支持innodb的物理热备份，支持完全备份、增量备份，而且速度非常快，支持innodb存储引起的数据在不同数据库之间迁移，支持复制模式下的从机备份恢复备份恢复。</p>
</li>
</ul>
<h2 id="监控"><a href="#监控" class="headerlink" title="监控"></a>监控</h2><h3 id="简述常见的监控软件？"><a href="#简述常见的监控软件？" class="headerlink" title="简述常见的监控软件？"></a>简述常见的监控软件？</h3><p>常见的监控软件有：</p>
<ul>
<li><code>Cacti</code>：是一套基于PHP、MySQL、SNMP及RRDTool开发的网络流量监测图形分析工具。</li>
<li><code>Zabbix</code>：Zabbix是一个企业级的高度集成开源监控软件，提供分布式监控解决方案。可以用来监控设备、服务等可用性和性能。</li>
<li><code>Open-falcon</code>：open-falcon是一款用golang和python写的监控系统，由小米启动这个项目。</li>
<li><code>Prometheus</code>：Prometheus是由SoundCloud开发的开源监控报警系统和时序列数据库(TSDB)。Prometheus使用Go语言开发，是Google BorgMon监控系统的开源版本。</li>
</ul>
<h3 id="简述Prometheus及其主要特性？"><a href="#简述Prometheus及其主要特性？" class="headerlink" title="简述Prometheus及其主要特性？"></a>简述Prometheus及其主要特性？</h3><p>Prometheus是一个已加入CNCF的开源监控报警系统和时序列数据库项目，通过不同的组件完成数据的采集，数据的存储和告警。</p>
<p>Prometheus主要特性：</p>
<ul>
<li><p>多维数据模型</p>
</li>
<li><ul>
<li>时间序列数据通过 metric 名和键值对来区分。</li>
<li>所有的 metrics 都可以设置任意的多维标签。</li>
<li>数据模型更随意，不需要刻意设置为以点分隔的字符串。</li>
<li>可以对数据模型进行聚合，切割和切片操作。</li>
<li>支持双精度浮点类型，标签可以设为全 unicode。</li>
</ul>
</li>
<li><p>灵活的查询语句（PromQL），可以利用多维数据完成复杂的查询</p>
</li>
<li><p>Prometheus server 是一个单独的二进制文件，不依赖（任何分布式）存储，支持 local 和 remote 不同模型</p>
</li>
<li><p>采用 http 协议，使用 pull 模式，拉取数据，或者通过中间网关推送方式采集数据</p>
</li>
<li><p>监控目标，可以采用服务发现或静态配置的方式</p>
</li>
<li><p>支持多种统计数据模型，图形化友好</p>
</li>
<li><p>高效：一个 Prometheus server 可以处理数百万的 metrics</p>
</li>
<li><p>适用于以机器为中心的监控以及高度动态面向服务架构的监控</p>
</li>
</ul>
<h3 id="简述Prometheus主要组件及其功能？"><a href="#简述Prometheus主要组件及其功能？" class="headerlink" title="简述Prometheus主要组件及其功能？"></a>简述Prometheus主要组件及其功能？</h3><p>Prometheus 的主要模块包含：prometheus server, exporters, push gateway, PromQL, Alertmanager, WebUI 等。</p>
<ul>
<li>1、<code>prometheus server</code>：定期从静态配置的 targets 或者服务发现（主要是DNS、consul、k8s、mesos等）的 targets 拉取数据，用于收集和存储时间序列数据。</li>
<li>2、<code>exporters</code>：负责向prometheus server做数据汇报，暴露一个http服务的接口给Prometheus server定时抓取。而不同的数据汇报由不同的exporters实现，比如监控主机有node-exporters，mysql有MySQL server exporter。</li>
<li>3、<code>push gateway</code>：主要使用场景为，当Prometheus 采用 pull 模式，可能由于不在一个子网或者防火墙原因，导致 Prometheus 无法直接拉取各个 target 数据。此时需要push gateway接入，以便于在监控业务数据的时候，将不同数据汇总, 由 Prometheus 统一收集。实现机制类似于zabbix-proxy功能。</li>
<li>4、<code>Alertmanager</code>：从 Prometheus server 端接收到 alerts 后，会进行去除重复数据，分组，并路由到对收的接受方式，发出报警，即主要实现prometheus的告警功能。AlertManager的整体工作流程如下图所示:</li>
<li>5、<code>webui</code>：Prometheus内置一个简单的Web控制台，可以查询指标，查看配置信息或者Service Discovery等，实践中通常结合Grafana，Prometheus仅作为Grafana的数据源。</li>
</ul>
<h3 id="简述Prometheus的机制？"><a href="#简述Prometheus的机制？" class="headerlink" title="简述Prometheus的机制？"></a>简述Prometheus的机制？</h3><p>Prometheus简单机制如下：</p>
<ul>
<li>Prometheus以其Server为核心，用于收集和存储时间序列数据。Prometheus Server 从监控目标中拉取数据，或通过push gateway间接的把监控目标的监控数据存储到本地HDD/SSD中。</li>
<li>用户接口界面通过各种UI使用PromQL查询语言从Server获取数据。</li>
<li>一旦Server检测到异常，会推送告警到AlertManager，由告警管理负责去通知相关方。</li>
</ul>
<h3 id="简述Prometheus中什么是时序数据？"><a href="#简述Prometheus中什么是时序数据？" class="headerlink" title="简述Prometheus中什么是时序数据？"></a>简述Prometheus中什么是时序数据？</h3><p>Prometheus 存储的是时序数据,，时序数据是指按照相同时序(相同的名字和标签)，以时间维度存储连续的数据的集合。时序(time series) 是由名字(Metric)，以及一组 key/value 标签定义的，具有相同的名字以及标签属于相同时序。</p>
<h3 id="简述Prometheus时序数据有哪些类型？"><a href="#简述Prometheus时序数据有哪些类型？" class="headerlink" title="简述Prometheus时序数据有哪些类型？"></a>简述Prometheus时序数据有哪些类型？</h3><p>Prometheus 时序数据分为 Counter, Gauge, Histogram, Summary 四种类型。</p>
<ul>
<li><code>Counter</code>：计数器表示收集的数据是按照某个趋势（增加／减少）一直变化的，通常用它记录服务请求总量，错误总数等。</li>
<li><code>Gauge</code>：计量器表示搜集的数据是一个瞬时的，与时间没有关系，可以任意变高变低，往往可以用来记录内存使用率、磁盘使用率等。</li>
<li><code>Histogram</code>：直方图 Histogram 主要用于对一段时间范围内的数据进行采样，（通常是请求持续时间或响应大小），并能够对其指定区间以及总数进行统计，通常我们用它计算分位数的直方图。</li>
<li><code>Summary</code>：汇总Summary 和 直方图Histogram 类似，主要用于表示一段时间内数据采样结果，（通常是请求持续时间或响应大小），它直接存储了 quantile 数据，而不是根据统计区间计算出来的。</li>
</ul>
<h3 id="简述Zabbix及其优势？"><a href="#简述Zabbix及其优势？" class="headerlink" title="简述Zabbix及其优势？"></a>简述Zabbix及其优势？</h3><p>Zabbix是一个企业级的高度集成开源监控软件，提供分布式监控解决方案。可以用来监控设备、服务等可用性和性能。其主要优势有：</p>
<ul>
<li>自由开放源代码产品，可以对其进行任意修改和二次开发，采用GPL协议；</li>
<li>安装和配置简单；</li>
<li>搭建环境简单，基于开源软件构建平台；</li>
<li>完全支持Linux、Unix、Windows、AIX、BSD等平台，采用C语言编码，系统占用小，数据采集性能和速度非常快；</li>
<li>数据采集持久存储到数据库，便于对监控数据的二次分析；</li>
<li>非常丰富的扩展能力，轻松实现自定义监控项和实现数据采集。</li>
</ul>
<h3 id="简述Zabbix体系架构？"><a href="#简述Zabbix体系架构？" class="headerlink" title="简述Zabbix体系架构？"></a>简述Zabbix体系架构？</h3><p>Zabbix体系相对清晰，其主要组件有：</p>
<ul>
<li><code>Zabbix Server</code>：负责接收agent发送的报告信息的核心组件，所有配置、统计数据及操作数据均由其组织进行。</li>
<li><code>Database Storage</code>：专用于存储所有配置信息，以及有zabbix收集的数据。</li>
<li><code>Web interface</code>（frontend）：zabbix的GUI接口，通常与server运行在同一台机器上。</li>
<li><code>Proxy</code>：可选组件，常用于分布式监控环境中，代理Server收集部分被监控数据并统一发往Server端。</li>
<li><code>Agent</code>：部署在被监控主机上，负责收集本地数据并发往Server端或者Proxy端。</li>
</ul>
<h3 id="简述Zabbix所支持的监控方式？"><a href="#简述Zabbix所支持的监控方式？" class="headerlink" title="简述Zabbix所支持的监控方式？"></a>简述Zabbix所支持的监控方式？</h3><p>目前由zabbix提供包括但不限于以下事项类型的支持：</p>
<ul>
<li><code>Zabbix agent checks</code>：这些客户端来进行数据采集，又分为Zabbix agent（被动模式：客户端等着服务器端来要数据），Zabbix agent (active)（主动模式：客户端主动发送数据到服务器端）</li>
<li><code>SNMP agent checks</code>：SNMP方式，如果要监控打印机网络设备等支持SNMP设备的话，但是又不能安装agent的设备。</li>
<li><code>SNMP traps</code> ：</li>
<li><code>IPMI checks</code>：IPMI即智能平台管理接口，现在是业界通过的标准。用户可以利用IPMI监视服务器的物理特性，如温度、电压、电扇工作状态、电源供应以及机箱入侵等。</li>
</ul>
<h4 id="简述Zabbix分布式及其适应场景？"><a href="#简述Zabbix分布式及其适应场景？" class="headerlink" title="简述Zabbix分布式及其适应场景？"></a>简述Zabbix分布式及其适应场景？</h4><p>zabbix proxy 可以代替 zabbix server 收集性能和可用性数据,然后把数据汇报给 zabbix server，并且在一定程度上分担了zabbix server 的压力。</p>
<p>此外，当所有agents和proxy报告给一个Zabbix server并且所有数据都集中收集时，使用proxy是实现集中式和分布式监控的最简单方法。</p>
<p>zabbix proxy 使用场景:</p>
<ul>
<li>监控远程区域设备</li>
<li>监控本地网络不稳定区域</li>
<li>当 zabbix 监控上千设备时,使用它来减轻 server 的压力</li>
<li>简化分布式监控的维护</li>
</ul>
<h2 id="网络管理"><a href="#网络管理" class="headerlink" title="网络管理"></a>网络管理</h2><h3 id="简述什么是CDN？"><a href="#简述什么是CDN？" class="headerlink" title="简述什么是CDN？"></a>简述什么是CDN？</h3><p>CDN即内容分发网络，是在现有网络中增加一层新的网络架构，从而实现将源站内容发布和传送到最靠近用户的边缘地区，使用户可以就近访问想要的内容，提高用户访问的响应速度。</p>
<blockquote>
<ul>
<li>作者：木二</li>
<li>链接：<a target="_blank" rel="noopener" href="https://www.yuque.com/docs/share/d3dd1e8e-6828-4da7-9e30-6a4f45c6fa8e">https://www.yuque.com/docs/share/d3dd1e8e-6828-4da7-9e30-6a4f45c6fa8e</a></li>
</ul>
</blockquote>
 
      <!-- reward -->
      
      <div id="reword-out">
        <div id="reward-btn">
          打赏
        </div>
      </div>
      
    </div>
    

    <!-- copyright -->
    
    <div class="declare">
      <ul class="post-copyright">
        <li>
          <i class="ri-copyright-line"></i>
          <strong>版权声明： </strong>
          
          本博客所有文章除特别声明外，著作权归作者所有。转载请注明出处！
          
        </li>
      </ul>
    </div>
    
    <footer class="article-footer">
       
<div class="share-btn">
      <span class="share-sns share-outer">
        <i class="ri-share-forward-line"></i>
        分享
      </span>
      <div class="share-wrap">
        <i class="arrow"></i>
        <div class="share-icons">
          
          <a class="weibo share-sns" href="javascript:;" data-type="weibo">
            <i class="ri-weibo-fill"></i>
          </a>
          <a class="weixin share-sns wxFab" href="javascript:;" data-type="weixin">
            <i class="ri-wechat-fill"></i>
          </a>
          <a class="qq share-sns" href="javascript:;" data-type="qq">
            <i class="ri-qq-fill"></i>
          </a>
          <a class="douban share-sns" href="javascript:;" data-type="douban">
            <i class="ri-douban-line"></i>
          </a>
          <!-- <a class="qzone share-sns" href="javascript:;" data-type="qzone">
            <i class="icon icon-qzone"></i>
          </a> -->
          
          <a class="facebook share-sns" href="javascript:;" data-type="facebook">
            <i class="ri-facebook-circle-fill"></i>
          </a>
          <a class="twitter share-sns" href="javascript:;" data-type="twitter">
            <i class="ri-twitter-fill"></i>
          </a>
          <a class="google share-sns" href="javascript:;" data-type="google">
            <i class="ri-google-fill"></i>
          </a>
        </div>
      </div>
</div>

<div class="wx-share-modal">
    <a class="modal-close" href="javascript:;"><i class="ri-close-circle-line"></i></a>
    <p>扫一扫，分享到微信</p>
    <div class="wx-qrcode">
      <img src="//api.qrserver.com/v1/create-qr-code/?size=150x150&data=http://example.com/2020/11/11/interview/IT%E8%BF%90%E7%BB%B4%E9%9D%A2%E8%AF%95%E9%97%AE%E9%A2%98%E6%80%BB%E7%BB%93-%E6%95%B0%E6%8D%AE%E5%BA%93%E3%80%81%E7%9B%91%E6%8E%A7%E3%80%81%E7%BD%91%E7%BB%9C%E7%AE%A1%E7%90%86/" alt="微信分享二维码">
    </div>
</div>

<div id="share-mask"></div>  
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/interview/" rel="tag">interview</a></li></ul>

    </footer>
  </div>

   
  <nav class="article-nav">
    
      <a href="/2020/11/11/es/Elasticsearch%20%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5/" class="article-nav-link">
        <strong class="article-nav-caption">上一篇</strong>
        <div class="article-nav-title">
          
            Elasticsearch 最佳实践.md
          
        </div>
      </a>
    
    
      <a href="/2020/11/11/interview/IT%E8%BF%90%E7%BB%B4%E9%9D%A2%E8%AF%95%E9%97%AE%E9%A2%98%E6%80%BB%E7%BB%93-%E8%BF%90%E7%BB%B4%E5%B7%A5%E5%85%B7%E3%80%81%E5%BC%80%E6%BA%90%E5%BA%94%E7%94%A8(Ceph%E3%80%81Docker%E3%80%81Apache%E3%80%81Nginx%E7%AD%89)/" class="article-nav-link">
        <strong class="article-nav-caption">下一篇</strong>
        <div class="article-nav-title">IT运维面试问题总结-运维工具、开源应用(Ceph、Docker、Apache、Nginx等).md</div>
      </a>
    
  </nav>

   
<!-- valine评论 -->
<div id="vcomments-box">
  <div id="vcomments"></div>
</div>
<script src="//cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/valine@1.4.14/dist/Valine.min.js"></script>
<script>
  new Valine({
    el: "#vcomments",
    app_id: "",
    app_key: "",
    path: window.location.pathname,
    avatar: "monsterid",
    placeholder: "给我的文章加点评论吧~",
    recordIP: true,
  });
  const infoEle = document.querySelector("#vcomments .info");
  if (infoEle && infoEle.childNodes && infoEle.childNodes.length > 0) {
    infoEle.childNodes.forEach(function (item) {
      item.parentNode.removeChild(item);
    });
  }
</script>
<style>
  #vcomments-box {
    padding: 5px 30px;
  }

  @media screen and (max-width: 800px) {
    #vcomments-box {
      padding: 5px 0px;
    }
  }

  #vcomments-box #vcomments {
    background-color: #fff;
  }

  .v .vlist .vcard .vh {
    padding-right: 20px;
  }

  .v .vlist .vcard {
    padding-left: 10px;
  }
</style>

 
     
</article>

</section>
      <footer class="footer">
  <div class="outer">
    <ul>
      <li>
        Copyrights &copy;
        2015-2020
        <i class="ri-heart-fill heart_icon"></i> TzWind
      </li>
    </ul>
    <ul>
      <li>
        
        
        
        由 <a href="https://hexo.io" target="_blank">Hexo</a> 强力驱动
        <span class="division">|</span>
        主题 - <a href="https://github.com/Shen-Yu/hexo-theme-ayer" target="_blank">Ayer</a>
        
      </li>
    </ul>
    <ul>
      <li>
        
        
        <span>
  <span><i class="ri-user-3-fill"></i>访问人数:<span id="busuanzi_value_site_uv"></span></s>
  <span class="division">|</span>
  <span><i class="ri-eye-fill"></i>浏览次数:<span id="busuanzi_value_page_pv"></span></span>
</span>
        
      </li>
    </ul>
    <ul>
      
    </ul>
    <ul>
      
    </ul>
    <ul>
      <li>
        <!-- cnzz统计 -->
        
        <script type="text/javascript" src='https://s9.cnzz.com/z_stat.php?id=1278069914&amp;web_id=1278069914'></script>
        
      </li>
    </ul>
  </div>
</footer>
      <div class="float_btns">
        <div class="totop" id="totop">
  <i class="ri-arrow-up-line"></i>
</div>

<div class="todark" id="todark">
  <i class="ri-moon-line"></i>
</div>

      </div>
    </main>
    <aside class="sidebar on">
      <button class="navbar-toggle"></button>
<nav class="navbar">
  
  <div class="logo">
    <a href="/"><img src="/images/ayer-side.svg" alt="Hexo"></a>
  </div>
  
  <ul class="nav nav-main">
    
    <li class="nav-item">
      <a class="nav-item-link" href="/">主页</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/archives">归档</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/categories">分类</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/tags">标签</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" target="_blank" rel="noopener" href="http://www.baidu.com">百度</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/friends">友链</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/2019/about">关于我</a>
    </li>
    
  </ul>
</nav>
<nav class="navbar navbar-bottom">
  <ul class="nav">
    <li class="nav-item">
      
      <a class="nav-item-link nav-item-search"  title="搜索">
        <i class="ri-search-line"></i>
      </a>
      
      
      <a class="nav-item-link" target="_blank" href="/atom.xml" title="RSS Feed">
        <i class="ri-rss-line"></i>
      </a>
      
    </li>
  </ul>
</nav>
<div class="search-form-wrap">
  <div class="local-search local-search-plugin">
  <input type="search" id="local-search-input" class="local-search-input" placeholder="Search...">
  <div id="local-search-result" class="local-search-result"></div>
</div>
</div>
    </aside>
    <script>
      if (window.matchMedia("(max-width: 768px)").matches) {
        document.querySelector('.content').classList.remove('on');
        document.querySelector('.sidebar').classList.remove('on');
      }
    </script>
    <div id="mask"></div>

<!-- #reward -->
<div id="reward">
  <span class="close"><i class="ri-close-line"></i></span>
  <p class="reward-p"><i class="ri-cup-line"></i>请我喝杯咖啡吧~</p>
  <div class="reward-box">
    
    
  </div>
</div>
    
<script src="/js/jquery-2.0.3.min.js"></script>


<script src="/js/lazyload.min.js"></script>

<!-- Tocbot -->


<script src="/js/tocbot.min.js"></script>

<script>
  tocbot.init({
    tocSelector: '.tocbot',
    contentSelector: '.article-entry',
    headingSelector: 'h1, h2, h3, h4, h5, h6',
    hasInnerContainers: true,
    scrollSmooth: true,
    scrollContainer: 'main',
    positionFixedSelector: '.tocbot',
    positionFixedClass: 'is-position-fixed',
    fixedSidebarOffset: 'auto'
  });
</script>

<script src="https://cdn.jsdelivr.net/npm/jquery-modal@0.9.2/jquery.modal.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jquery-modal@0.9.2/jquery.modal.min.css">
<script src="https://cdn.jsdelivr.net/npm/justifiedGallery@3.7.0/dist/js/jquery.justifiedGallery.min.js"></script>

<script src="/dist/main.js"></script>

<!-- ImageViewer -->

<!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">

    <!-- Background of PhotoSwipe. 
         It's a separate element as animating opacity is faster than rgba(). -->
    <div class="pswp__bg"></div>

    <!-- Slides wrapper with overflow:hidden. -->
    <div class="pswp__scroll-wrap">

        <!-- Container that holds slides. 
            PhotoSwipe keeps only 3 of them in the DOM to save memory.
            Don't modify these 3 pswp__item elements, data is added later on. -->
        <div class="pswp__container">
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
        </div>

        <!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
        <div class="pswp__ui pswp__ui--hidden">

            <div class="pswp__top-bar">

                <!--  Controls are self-explanatory. Order can be changed. -->

                <div class="pswp__counter"></div>

                <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>

                <button class="pswp__button pswp__button--share" style="display:none" title="Share"></button>

                <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>

                <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>

                <!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
                <!-- element will get class pswp__preloader--active when preloader is running -->
                <div class="pswp__preloader">
                    <div class="pswp__preloader__icn">
                        <div class="pswp__preloader__cut">
                            <div class="pswp__preloader__donut"></div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
                <div class="pswp__share-tooltip"></div>
            </div>

            <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
            </button>

            <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
            </button>

            <div class="pswp__caption">
                <div class="pswp__caption__center"></div>
            </div>

        </div>

    </div>

</div>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/default-skin/default-skin.min.css">
<script src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe-ui-default.min.js"></script>

<script>
    function viewer_init() {
        let pswpElement = document.querySelectorAll('.pswp')[0];
        let $imgArr = document.querySelectorAll(('.article-entry img:not(.reward-img)'))

        $imgArr.forEach(($em, i) => {
            $em.onclick = () => {
                // slider展开状态
                // todo: 这样不好，后面改成状态
                if (document.querySelector('.left-col.show')) return
                let items = []
                $imgArr.forEach(($em2, i2) => {
                    let img = $em2.getAttribute('data-idx', i2)
                    let src = $em2.getAttribute('data-target') || $em2.getAttribute('src')
                    let title = $em2.getAttribute('alt')
                    // 获得原图尺寸
                    const image = new Image()
                    image.src = src
                    items.push({
                        src: src,
                        w: image.width || $em2.width,
                        h: image.height || $em2.height,
                        title: title
                    })
                })
                var gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, {
                    index: parseInt(i)
                });
                gallery.init()
            }
        })
    }
    viewer_init()
</script>

<!-- MathJax -->

<!-- Katex -->

<!-- busuanzi  -->


<script src="/js/busuanzi-2.3.pure.min.js"></script>


<!-- ClickLove -->

<!-- ClickBoom1 -->

<!-- ClickBoom2 -->

<!-- CodeCopy -->


<link rel="stylesheet" href="/css/clipboard.css">

<script src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js"></script>
<script>
  function wait(callback, seconds) {
    var timelag = null;
    timelag = window.setTimeout(callback, seconds);
  }
  !function (e, t, a) {
    var initCopyCode = function(){
      var copyHtml = '';
      copyHtml += '<button class="btn-copy" data-clipboard-snippet="">';
      copyHtml += '<i class="ri-file-copy-2-line"></i><span>COPY</span>';
      copyHtml += '</button>';
      $(".highlight .code pre").before(copyHtml);
      $(".article pre code").before(copyHtml);
      var clipboard = new ClipboardJS('.btn-copy', {
        target: function(trigger) {
          return trigger.nextElementSibling;
        }
      });
      clipboard.on('success', function(e) {
        let $btn = $(e.trigger);
        $btn.addClass('copied');
        let $icon = $($btn.find('i'));
        $icon.removeClass('ri-file-copy-2-line');
        $icon.addClass('ri-checkbox-circle-line');
        let $span = $($btn.find('span'));
        $span[0].innerText = 'COPIED';
        
        wait(function () { // 等待两秒钟后恢复
          $icon.removeClass('ri-checkbox-circle-line');
          $icon.addClass('ri-file-copy-2-line');
          $span[0].innerText = 'COPY';
        }, 2000);
      });
      clipboard.on('error', function(e) {
        e.clearSelection();
        let $btn = $(e.trigger);
        $btn.addClass('copy-failed');
        let $icon = $($btn.find('i'));
        $icon.removeClass('ri-file-copy-2-line');
        $icon.addClass('ri-time-line');
        let $span = $($btn.find('span'));
        $span[0].innerText = 'COPY FAILED';
        
        wait(function () { // 等待两秒钟后恢复
          $icon.removeClass('ri-time-line');
          $icon.addClass('ri-file-copy-2-line');
          $span[0].innerText = 'COPY';
        }, 2000);
      });
    }
    initCopyCode();
  }(window, document);
</script>


<!-- CanvasBackground -->


    
  </div>
</body>

</html>